/**
 * File:   LauncherDialog.java
 * Author: Gvennet
 */
package gui.main;

import dht.identifier.identifier.Identifier;
import dht.identifier.identifier.Identifiers;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;

/**
 * todo write javadoc
 */
public final class LauncherDialog extends JDialog
{

	private String answer = null;

	private JComboBox ipComboBox;

	private JTextField port;

	private JTextField id;

	private JTextField timeout;

	private JTextField storageTime;

	private JTextField statisticsPeriod;

	private JTextField maxNodes;

	private int cleaner;

	public LauncherDialog()
	{
		super();
		setModal(true);
		setResizable(false);
		setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
		addWindowListener(new WindowAdapter()
		{
			@Override
			public void windowClosing(WindowEvent e)
			{
				answer = "Cancel";
				setVisible(false);
			}
		});

		JLabel ipLabel = new JLabel("Введите IP-адрес");
		ipComboBox = new JComboBox(availableIpAddresses().toArray());

		JLabel portLabel = new JLabel("Введите порт");
		port = new JTextField("0");

		JLabel idLabel = new JLabel("Введите идентификатор");
		id = new JTextField();

		JLabel timeoutLabel = new JLabel("Введите максимальное время ожидания ответа на сообщения, сек");
		timeout = new JTextField("10");

		JLabel storageTimeLabel = new JLabel("Введите время хранения данных, мин");
		storageTime = new JTextField("1");

		JLabel statisticsPeriodLabel = new JLabel("Введите период сбора статистики, сек");
		statisticsPeriod = new JTextField("");

		JLabel maxNodesLabel = new JLabel("Введите максимальный размер таблицы маршрутизации");
		maxNodes = new JTextField("10");

		JLabel cleanerLabel = new JLabel("Выберите вариант организации таблицы маршрутизации");
		ButtonGroup group = new ButtonGroup();


		JRadioButton treeCleanerButton = new JRadioButton(new TreeCleanerAction());

		JRadioButton simpleCleanerButton = new JRadioButton(new SimpleCleanerAction());

		JRadioButton complexCleanerButton = new JRadioButton(new ComplexCleanerAction());

		JRadioButton withoutCleanerButton = new JRadioButton(new WithoutCleanerAction());

		treeCleanerButton.setSelected(true);

		group.add(withoutCleanerButton);
		group.add(simpleCleanerButton);
		group.add(complexCleanerButton);
		group.add(treeCleanerButton);

		JButton cancelButton = new JButton(new CancelAction());
		JButton okButton = new JButton(new OkAction());
		// okButton.setSelected(true);

		GroupLayout layout = new GroupLayout(getContentPane());
		getContentPane().setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);
		layout.setHorizontalGroup(layout.createParallelGroup()
				.addGroup(layout.createSequentialGroup().addComponent(ipLabel).addComponent(ipComboBox))
				.addGroup(layout.createSequentialGroup().addComponent(portLabel).addComponent(port))
				.addGroup(layout.createSequentialGroup().addComponent(idLabel).addComponent(id))
				.addGroup(layout.createSequentialGroup().addComponent(timeoutLabel).addComponent(timeout))
				.addGroup(layout.createSequentialGroup().addComponent(storageTimeLabel).addComponent(storageTime))
				.addGroup(layout.createSequentialGroup().addComponent(statisticsPeriodLabel).addComponent(statisticsPeriod))
				.addGroup(layout.createSequentialGroup().addComponent(maxNodesLabel).addComponent(maxNodes))
				.addComponent(cleanerLabel)
				.addComponent(treeCleanerButton)
				.addComponent(simpleCleanerButton)
				.addComponent(complexCleanerButton)
				.addComponent(withoutCleanerButton)
				.addGroup(GroupLayout.Alignment.CENTER, layout.createSequentialGroup().addComponent(cancelButton).addComponent(okButton)));
		layout.setVerticalGroup(layout.createSequentialGroup()
				.addGap(10)
				.addGroup(layout.createParallelGroup().addComponent(ipLabel).addComponent(ipComboBox))
				.addGroup(layout.createParallelGroup().addComponent(portLabel).addComponent(port))
				.addGroup(layout.createParallelGroup().addComponent(idLabel).addComponent(id))
				.addGroup(layout.createParallelGroup().addComponent(timeoutLabel).addComponent(timeout))
				.addGroup(layout.createParallelGroup().addComponent(storageTimeLabel).addComponent(storageTime))
				.addGroup(layout.createParallelGroup().addComponent(statisticsPeriodLabel).addComponent(statisticsPeriod))
				.addGroup(layout.createParallelGroup().addComponent(maxNodesLabel).addComponent(maxNodes))
				.addGap(30)
				.addComponent(cleanerLabel)
				.addComponent(treeCleanerButton)
				.addComponent(simpleCleanerButton)
				.addComponent(complexCleanerButton)
				.addComponent(withoutCleanerButton)
				.addGap(20)
				.addGroup(layout.createParallelGroup().addComponent(okButton).addComponent(cancelButton)));
		layout.linkSize(SwingConstants.HORIZONTAL, ipLabel, portLabel, idLabel, timeoutLabel, storageTimeLabel,
				statisticsPeriodLabel, maxNodesLabel);
		layout.linkSize(SwingConstants.HORIZONTAL, okButton, cancelButton);
		layout.linkSize(SwingConstants.VERTICAL, ipLabel, ipComboBox);
		layout.linkSize(SwingConstants.VERTICAL, portLabel, port);
		layout.linkSize(SwingConstants.VERTICAL, idLabel, id);
		layout.linkSize(SwingConstants.VERTICAL, storageTimeLabel, storageTime);
		layout.linkSize(SwingConstants.VERTICAL, timeoutLabel, timeout);
		layout.linkSize(SwingConstants.VERTICAL, statisticsPeriodLabel, statisticsPeriod);
		layout.linkSize(SwingConstants.VERTICAL, maxNodesLabel, maxNodes);

		setLocationByPlatform(true);

		pack();
	}

	public String getAnswer()
	{
		return answer;
	}

	public InetAddress getIpAddress()
	{
		try
		{
			return InetAddress.getByName(ipComboBox.getSelectedItem().toString());
		}
		catch (UnknownHostException e)
		{
			throw new RuntimeException(e);
		}
	}

	public int getPort()
	{
		return Integer.valueOf(port.getText());
	}

	public Identifier getId() throws ParseException
	{
		return Identifiers.convertFromString(id.getText());
	}

	public long getTimeout()
	{
		return Long.valueOf(timeout.getText());
	}

	public long getStorageTime()
	{
		return Long.valueOf(storageTime.getText());
	}

	public long getStatisticsPeriod()
	{
		try
		{
			return Long.valueOf(statisticsPeriod.getText());
		}
		catch (NumberFormatException e)
		{
			return Long.MAX_VALUE;
		}
	}

	public int getMaxNodes()
	{
		return Integer.valueOf(maxNodes.getText());
	}

	public int getCleaner()
	{
		return cleaner;
	}

	private class WithoutCleanerAction extends AbstractAction
	{

		WithoutCleanerAction()
		{
			super("Без оптимизации");
			putValue(SHORT_DESCRIPTION, "Узлы удаляются по таймауту");
		}

		//@Override

		public void actionPerformed(ActionEvent event)
		{
			cleaner = 3;
		}
	}

	private class SimpleCleanerAction extends AbstractAction
	{

		SimpleCleanerAction()
		{
			super("Удаление неотвечающих узлов");
			putValue(SHORT_DESCRIPTION, "Опрашиваются узлы таблицы маршрутизации и удаляются неотвечающие");
		}

		//@Override

		public void actionPerformed(ActionEvent event)
		{
			cleaner = 1;
		}
	}

	private class ComplexCleanerAction extends AbstractAction
	{

		ComplexCleanerAction()
		{
			super("Удаление узлов, расстояние до идентификаторов которых максимально");
			putValue(SHORT_DESCRIPTION, "Удаляются узлы, наиболее далёкие от данного");
		}

		//@Override

		public void actionPerformed(ActionEvent event)
		{
			cleaner = 2;
		}
	}

	private class TreeCleanerAction extends AbstractAction
	{

		TreeCleanerAction()
		{
			super("Приведение таблицы маршрутизации к древовидной структуре");
			putValue(SHORT_DESCRIPTION, "Таблица маршрутизации приводится к древовидной структуре");
		}

		//@Override

		public void actionPerformed(ActionEvent event)
		{
			cleaner = 0;
		}
	}

	private class OkAction extends AbstractAction
	{

		OkAction()
		{
			super("Продолжить");
		}

		//@Override

		public void actionPerformed(ActionEvent e)
		{
			answer = "Ok";
			setVisible(false);

		}

	}

	private class CancelAction extends AbstractAction
	{

		CancelAction()
		{
			super("Отменить");
		}

		//@Override

		public void actionPerformed(ActionEvent e)
		{
			answer = "Cancel";
			setVisible(false);
		}

	}

	private List<String> availableIpAddresses()
	{
		List<String> stringAddresses = new LinkedList<String>();

		try
		{
			Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
			while (interfaces.hasMoreElements())
			{
				Enumeration<InetAddress> addresses = interfaces.nextElement().getInetAddresses();
				while (addresses.hasMoreElements())
				{
					stringAddresses.add(addresses.nextElement().getHostAddress());
				}

			}
		}
		catch (SocketException e)
		{
			throw new RuntimeException(e);
		}

		return stringAddresses;
	}
}
